/** 
	@file ConfigHooks.cpp
	@brief Config panel for login/logout hooks
*/
/*
pGina ldapAuth code - based upon skeleton code for pGina plugin development
Copyright (C) 2002 Micah Cooper

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Email: coopermj@muohio.edu
Snail Mail:
	Micah Cooper
	212A Kreger Hall
	Miami University
	Oxford OH  45056
*/
// ConfigHooks.cpp : implementation file
//

#include "stdafx.h"
#include "winLDAP.h"
#include "ConfigHooks.h"
#include ".\confighooks.h"
#include "SelectFile.h"

// CConfigHooks dialog

IMPLEMENT_DYNAMIC(CConfigHooks, CDialog)
CConfigHooks::CConfigHooks(CWnd* pParent /*=NULL*/)
	: CDialog(CConfigHooks::IDD, pParent)
	, m_newLoginHook(_T(""))
	, m_newLogoutHook(_T(""))
{
	hasLoaded = false;
}

CConfigHooks::~CConfigHooks()
{
}

void CConfigHooks::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_LOGINHOOK, m_newLoginHook);
	DDX_Control(pDX, IDC_LOGINHOOKLIST, m_LoginHookList);
	DDX_Text(pDX, IDC_LOGOUTHOOK, m_newLogoutHook);
	DDX_Control(pDX, IDC_LOGOUTHOOKLIST, m_LogoutHookList);

	if(!hasLoaded)
	{
		loadListsFromReg();
		hasLoaded = true;
	}
}


BEGIN_MESSAGE_MAP(CConfigHooks, CDialog)
	ON_BN_CLICKED(IDC_ADDLOGINHOOK, OnAddLoginHook)
	ON_BN_CLICKED(IDC_DELLOGINHOOK, OnRemoveLoginHook)
	ON_BN_CLICKED(IDC_ADDLOGOUTHOOK, OnAddLogoutHook)
	ON_BN_CLICKED(IDC_DELLOGOUTHOOK, OnRemoveLogoutHook)
	ON_BN_CLICKED(IDC_BROWSEFILES, OnBrowseLogin)
	ON_BN_CLICKED(IDC_BROWSEFILES2, OnBrowseLogout)
	ON_BN_CLICKED(IDC_MOVECTXUP, OnMoveLoginUp)
	ON_BN_CLICKED(IDC_MOVECTXDWN, OnMoveLoginDown)
	ON_BN_CLICKED(IDC_MOVECTXUP5, OnMoveLogoutUp)
	ON_BN_CLICKED(IDC_MOVECTXDWN2, OnMoveLogoutDown)
END_MESSAGE_MAP()


// CConfigHooks message handlers
void CConfigHooks::OnOK()
{
	return;
}

void CConfigHooks::OnAddLoginHook()
{
	UpdateData(TRUE);
	if (m_newLoginHook == "") {
		MessageBox(L"Please enter a valid executable.", L"LDAPAuth", MB_OK);
		return;
	}
	m_LoginHookList.AddString(m_newLoginHook);
	m_newLoginHook = TEXT("");
	UpdateData(FALSE);
}

void CConfigHooks::OnRemoveLoginHook()
{
	// TODO: Add your control notification handler code here
	if(m_LoginHookList.GetCurSel() >= 0)
		m_LoginHookList.DeleteString(m_LoginHookList.GetCurSel());
}

void CConfigHooks::OnAddLogoutHook()
{
	UpdateData(TRUE);
	if (m_newLogoutHook == "") {
		MessageBox(L"Please enter a valid executable.", L"LDAPAuth", MB_OK);
		return;
	}
	m_LogoutHookList.AddString(m_newLogoutHook);
	m_newLogoutHook = TEXT("");
	UpdateData(FALSE);
}

void CConfigHooks::OnRemoveLogoutHook()
{
	// TODO: Add your control notification handler code here
	if(m_LogoutHookList.GetCurSel() >= 0)
		m_LogoutHookList.DeleteString(m_LogoutHookList.GetCurSel());
}

void CConfigHooks::saveListsToReg(void)
{
	WCHAR currentName[256];
	CString value = NULL;
	int x = 0;

	// now for login hooks
	for(x = 0; x < m_LoginHookList.GetCount(); x++)
	{
		m_LoginHookList.GetText(x,value);
		swprintf(currentName,TEXT("loginHook%d"),x);
		regWriteString(value.GetBuffer(value.GetLength()),currentName);
	}

	// Now loop through and delete any existing contexts above our last saved one
	x = m_LoginHookList.GetCount();
	swprintf(currentName,TEXT("loginHook%d"),x);
	value = regReadString(currentName);

	while(value.GetLength() > 0)
	{
		regDelValue(currentName);
		x++;
		swprintf(currentName,TEXT("loginHook%d"),x);
		value = regReadString(currentName);
	}

	// now for logout hooks
	for(x = 0; x < m_LogoutHookList.GetCount(); x++)
	{
		m_LogoutHookList.GetText(x,value);
		swprintf(currentName,TEXT("logoutHook%d"),x);
		regWriteString(value.GetBuffer(value.GetLength()),currentName);
	}

	// Now loop through and delete any existing contexts above our last saved one
	x = m_LogoutHookList.GetCount();
	swprintf(currentName,TEXT("logoutHook%d"),x);
	value = regReadString(currentName);

	while(value.GetLength() > 0)
	{
		regDelValue(currentName);
		x++;
		swprintf(currentName,TEXT("logoutHook%d"),x);
		value = regReadString(currentName);
	}
}

void CConfigHooks::loadListsFromReg(void)
{
	// Load the content for the lists from the registry 
	WCHAR currentName[256];
	int x = 0;
	CString contextValue = NULL;
	
	// Then loginHookOKx
	swprintf(currentName,TEXT("loginHook%d"),x);
	contextValue = regReadString(currentName);
	while(contextValue.GetLength() > 0)
	{
		m_LoginHookList.AddString(contextValue);
		x++;
        swprintf(currentName,TEXT("loginHook%d"),x);
		contextValue = regReadString(currentName);
	}

	x = 0;
	// Then logoutHookOKx
	swprintf(currentName,TEXT("logoutHook%d"),x);
	contextValue = regReadString(currentName);
	while(contextValue.GetLength() > 0)
	{
		m_LogoutHookList.AddString(contextValue);
		x++;
        swprintf(currentName,TEXT("logoutHook%d"),x);
		contextValue = regReadString(currentName);
	}
}

void CConfigHooks::OnSave()
{
	UpdateData(TRUE);
	WCHAR currentName[256];
	CString value = NULL;
	int x = 0;

	// now for login hooks
	for(x = 0; x < m_LoginHookList.GetCount(); x++)
	{
		m_LoginHookList.GetText(x,value);
		swprintf(currentName,TEXT("loginHook%d"),x);
		regWriteString(value.GetBuffer(value.GetLength()),currentName);
	}

	// Now loop through and delete any existing contexts above our last saved one
	x = m_LoginHookList.GetCount();
	swprintf(currentName,TEXT("loginHook%d"),x);
	value = regReadString(currentName);

	while(value.GetLength() > 0)
	{
		regDelValue(currentName);
		x++;
		swprintf(currentName,TEXT("loginHook%d"),x);
		value = regReadString(currentName);
	}

	// now for logout hooks
	for(x = 0; x < m_LogoutHookList.GetCount(); x++)
	{
		m_LogoutHookList.GetText(x,value);
		swprintf(currentName,TEXT("logoutHook%d"),x);
		regWriteString(value.GetBuffer(value.GetLength()),currentName);
	}

	// Now loop through and delete any existing contexts above our last saved one
	x = m_LogoutHookList.GetCount();
	swprintf(currentName,TEXT("logoutHook%d"),x);
	value = regReadString(currentName);

	while(value.GetLength() > 0)
	{
		regDelValue(currentName);
		x++;
		swprintf(currentName,TEXT("logoutHook%d"),x);
		value = regReadString(currentName);
	}
}

void CConfigHooks::OnBrowseLogin()
{
	// TODO: Add your control notification handler code here
	// Create a new file selection dialog box
	//    The parameters state that we want to Open a file,
	//	  hide files marked as read-only, filter for *.pgina, *.dll and *.*
	//    and we do not belong to a particular hWnd for callback.
	SelectFile *t = new SelectFile(TRUE,NULL,NULL,OFN_HIDEREADONLY, TEXT("Executable files (*.exe)|*.exe|All files (*.*)|*.*"), NULL);
	
	// Call the file selection dialog
	if(t->DoModal() == IDOK)
	{	
		// The user selected a file, or pressed okay
		//   so call LoadFunctions on the selected path.
		UpdateData(TRUE);
		m_newLoginHook = t->GetPathName();
		UpdateData(FALSE);
	}
	else
	{
		// If we get here the user canceled the open process
		m_newLoginHook = TEXT("");
	}
}

void CConfigHooks::OnBrowseLogout()
{
	// TODO: Add your control notification handler code here
	// Create a new file selection dialog box
	//    The parameters state that we want to Open a file,
	//	  hide files marked as read-only, filter for *.pgina, *.dll and *.*
	//    and we do not belong to a particular hWnd for callback.
	SelectFile *t = new SelectFile(TRUE,NULL,NULL,OFN_HIDEREADONLY, TEXT("Executable files (*.exe)|*.bat|All files (*.*)|*.*"), NULL);
	
	// Call the file selection dialog
	if(t->DoModal() == IDOK)
	{	
		// The user selected a file, or pressed okay
		//   so call LoadFunctions on the selected path.
		UpdateData(TRUE);
		m_newLogoutHook = t->GetPathName();
		UpdateData(FALSE);
	}
	else
	{
		// If we get here the user canceled the open process
		m_newLogoutHook = TEXT("");
	}
}

void CConfigHooks::swapItem(CListBox *listbox,int old, int next)
{
	CString valueA;
	CString valueB;
	

	listbox->GetText(old,valueA);
	listbox->DeleteString(old);
	listbox->InsertString(next,valueA);	
	listbox->SetCurSel(next);
}

void CConfigHooks::OnMoveLoginUp()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if(m_LoginHookList.GetCurSel() > 0)
		swapItem(&m_LoginHookList,m_LoginHookList.GetCurSel(),m_LoginHookList.GetCurSel() - 1);
	UpdateData(FALSE);
}

void CConfigHooks::OnMoveLoginDown()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if(m_LoginHookList.GetCurSel() >= 0 && m_LoginHookList.GetCurSel() < m_LoginHookList.GetCount() - 1)
		swapItem(&m_LoginHookList,m_LoginHookList.GetCurSel(),m_LoginHookList.GetCurSel() + 1);
	UpdateData(FALSE);
}

void CConfigHooks::OnMoveLogoutUp()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if(m_LogoutHookList.GetCurSel() > 0)
		swapItem(&m_LogoutHookList,m_LogoutHookList.GetCurSel(),m_LogoutHookList.GetCurSel() - 1);
	UpdateData(FALSE);
}

void CConfigHooks::OnMoveLogoutDown()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if(m_LogoutHookList.GetCurSel() >= 0 && m_LogoutHookList.GetCurSel() < m_LogoutHookList.GetCount() - 1)
		swapItem(&m_LogoutHookList,m_LogoutHookList.GetCurSel(),m_LogoutHookList.GetCurSel() + 1);
	UpdateData(FALSE);
}
